#include "FileOperate.h"
#include "StringTool.h"


NTSTATUS KernelDelFile(char *filePath) {

	NTSTATUS status = STATUS_SUCCESS;


	auto uniStringPath = CharPtrToUnicodeString(filePath);

	OBJECT_ATTRIBUTES obja = { 0 };

	InitializeObjectAttributes(&obja, &uniStringPath, OBJ_CASE_INSENSITIVE, NULL, NULL);

	status = ZwDeleteFile(&obja);

	if (!NT_SUCCESS(status)) {
		KdPrint(("[myddk] del file failed"));
	}

	return status;
}

static UNICODE_STRING StringSrcDriver = RTL_CONSTANT_STRING(L"\\??\\C:\\Users\\Administrator\\Desktop\\PCHunter64as.sys");
static UNICODE_STRING StringDstDriver = RTL_CONSTANT_STRING(L"\\??\\C:\\Users\\Administrator\\Desktop\\PCHunter64as.sys.bak");
#define PAGE_SIZE_MM    (4096)

NTSTATUS KernelCopyFile(PUNICODE_STRING dst, PUNICODE_STRING src)
{
	HANDLE FileHandle1, FileHandle2;
	IO_STATUS_BLOCK block1, block2;
	OBJECT_ATTRIBUTES ot1, ot2;
	NTSTATUS status;
	//block1
	char *Buff;
	LARGE_INTEGER ByteOffset1, ByteOffset2;

	if (KeGetCurrentIrql() != PASSIVE_LEVEL) {
		KdPrint(("[+] infinityhook: STATUS_INVALID_DEVICE_STATE\n"));
		return STATUS_INVALID_DEVICE_STATE;
	}

	Buff = (char *)ExAllocatePool(NonPagedPool, PAGE_SIZE_MM);
	if (Buff == NULL) {
		return STATUS_INVALID_DEVICE_STATE;
	}
	block1.Pointer = NULL;
	block1.Information = NULL;
	block2.Pointer = NULL;
	block2.Information = NULL;

	InitializeObjectAttributes(&ot1, dst, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
	InitializeObjectAttributes(&ot2, src, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);

	status = ZwCreateFile(&FileHandle1,
		GENERIC_WRITE,
		&ot1, &block1,
		NULL, FILE_ATTRIBUTE_NORMAL, 0,
		FILE_OVERWRITE_IF,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL, 0);
	if (!NT_SUCCESS(status)) {
		KdPrint(("ZwCreateFile File  %wZ Error:%d\n", dst, status));
		goto out;
	}
	status = ZwCreateFile(&FileHandle2,
		GENERIC_READ,
		&ot2, &block2,
		NULL, FILE_ATTRIBUTE_NORMAL, 0,
		FILE_OPEN,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL, 0);
	if (!NT_SUCCESS(status)) {
		KdPrint(("ZwCreateFile File  %wZ Error:%d\n", src, status));
		goto out_2;
	}
	KdPrint(("ZwCreateFile Tow File  Ok,  Next to Read and Write!!!!\n"));

	ByteOffset1.QuadPart = 0;
	ByteOffset2.QuadPart = 0;

	do {
		status = ZwReadFile(FileHandle2,
			NULL,
			NULL,
			NULL,
			&block2,
			Buff,
			PAGE_SIZE_MM,
			&ByteOffset2,
			NULL);
		if (!NT_SUCCESS(status)) {
			KdPrint(("ZwReadFile Error!!!"));
			goto out_1;
		}
		if (block2.Information == 0) {
			KdPrint(("ZwReadFile Zero byte!!!"));
			goto out_1;
		}
		KdPrint(("ZwReadFile block2 Information : %d", (int)block2.Information));

		ByteOffset2.QuadPart += block2.Information;

		status = ZwWriteFile(FileHandle1,
			NULL,
			NULL,
			NULL,
			&block1,
			Buff,
			(ULONG)block2.Information,
			&ByteOffset1,
			NULL);
		if (!NT_SUCCESS(status)) {
			KdPrint(("ZwWriteFile Error!!!"));
			goto out_1;
		}
		ByteOffset1.QuadPart += block1.Information;
		KdPrint(("ZwWriteFile block1 Information : %d", (int)block1.Information));
	} while (1);

out_1:
	ZwClose(FileHandle2);
out_2:
	ZwClose(FileHandle1);
out:
	ExFreePool(Buff);
	return status;
}

